#include "eparking_sqlite.h"

EParkingSqlite::EParkingSqlite(const QString& dbName)
{
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(dbName);

    if (!db.open()) {
        qWarning() << "Database connection error:" << db.lastError().text();
        return;
    }

    // 初始化数据库表结构
    QSqlQuery query(db);
    query.exec("CREATE TABLE IF NOT EXISTS vehicle_records ("
               "id INTEGER PRIMARY KEY AUTOINCREMENT,"
               "plate_number TEXT NOT NULL,"
               "entry_time DATETIME NOT NULL,"
               "exit_time DATETIME,"
               "bill REAL DEFAULT 0,"
               "is_internal BOOLEAN DEFAULT 0)");

    query.exec("CREATE TABLE IF NOT EXISTS internal_vehicles ("
               "plate_number TEXT PRIMARY KEY,"
               "valid_from DATETIME NOT NULL,"
               "valid_to DATETIME NOT NULL)");

    qDebug() << "DATABASE INIT";
}

EParkingSqlite::~EParkingSqlite()
{
    if (db.isOpen()) {
        db.close();
    }
}

QSqlDatabase EParkingSqlite::getDatabase() {
    return db;
}

bool EParkingSqlite::checkDatabase()
{
    if (!db.isOpen()) {
        qWarning() << "数据库连接已关闭，尝试重连...";
        if (!db.open()) {
            qCritical() << "重连失败:" << db.lastError().text();
            return false;
        }
    }
    return true;
}


bool EParkingSqlite::logVehicleEntry(const QString& plateNumber)
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    query.prepare("INSERT INTO vehicle_records (plate_number, entry_time, is_internal) "
                  "VALUES (:plate, :entry, :is_internal)");
    query.bindValue(":plate", plateNumber);
    query.bindValue(":entry", QDateTime::currentDateTime());
    query.bindValue(":is_internal", isInternalVehicleValid(plateNumber));

    return query.exec();
}

bool EParkingSqlite::logVehicleExit(const QString& plateNumber, double bill)
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    query.prepare("UPDATE vehicle_records SET "
                  "exit_time = :exit, bill = :bill "
                  "WHERE plate_number = :plate AND exit_time IS NULL");
    query.bindValue(":exit", QDateTime::currentDateTime());
    query.bindValue(":bill", bill);
    query.bindValue(":plate", plateNumber);

    return query.exec();
}

bool EParkingSqlite::addInternalVehicle(const QString& plateNumber,
                                        const QDateTime& from, const QDateTime& to)
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    query.prepare("INSERT OR REPLACE INTO internal_vehicles "
                  "VALUES (:plate, :from, :to)");
    query.bindValue(":plate", plateNumber);
    query.bindValue(":from", from);
    query.bindValue(":to", to);

    return query.exec();
}

bool EParkingSqlite::isInternalVehicle(const QString& plateNumber)
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    query.prepare("SELECT 1 FROM internal_vehicles "
                  "WHERE plate_number = :plate ");
    query.bindValue(":plate", plateNumber);

    return query.exec() && query.next();
}

bool EParkingSqlite::isInternalVehicleValid(const QString& plateNumber)
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    query.prepare("SELECT 1 FROM internal_vehicles "
                  "WHERE plate_number = :plate "
                  "AND valid_from <= :now AND valid_to >= :now");
    query.bindValue(":plate", plateNumber);
    query.bindValue(":now", QDateTime::currentDateTime());

    return query.exec() && query.next();
}

bool EParkingSqlite::removeInternalVehicle(const QString& plateNumber)
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    query.prepare("DELETE FROM internal_vehicles WHERE plate_number = :plate");
    query.bindValue(":plate", plateNumber.trimmed().toUpper());

    if (!query.exec()) {
        qWarning() << "删除内部车辆失败：" << query.lastError().text()
            << "车牌号：" << plateNumber;
        return false;
    }

    return query.numRowsAffected() > 0;
}

QList<QString> EParkingSqlite::getCurrentParkingList()
{
    checkDatabase();
    QList<QString> result;
    QSqlQuery query("SELECT plate_number FROM vehicle_records "
                    "WHERE exit_time IS NULL");
    while (query.next()) {
        result.append(query.value(0).toString());
    }
    return result;
}


int EParkingSqlite::getCurrentParkingCount()
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    if (!query.prepare("SELECT COUNT(id) FROM vehicle_records WHERE exit_time IS NULL")) {
        qWarning() << "Prepare error:" << query.lastError().text();
        return -1;
    }

    if (!query.exec()) {
        qWarning() << "Execute error:" << query.lastError().text();
        return -1;
    }

    return query.next() ? query.value(0).toInt() : -1;
}

int EParkingSqlite::getCurrentInnerCarCount()
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    if (!query.prepare("SELECT * FROM internal_vehicles")) {
        qWarning() << "Prepare error:" << query.lastError().text();
        return -1;
    }

    if (!query.exec()) {
        qWarning() << "Execute error:" << query.lastError().text();
        return -1;
    }

    return query.next() ? query.value(0).toInt() : 0;
}

double EParkingSqlite::getTodayEarnings()
{
    if (!checkDatabase()) return false;
    QSqlQuery query;
    const QString sql =
        "SELECT COALESCE(SUM(bill), 0) FROM vehicle_records "
        "WHERE strftime('%Y-%m-%d', exit_time) = strftime('%Y-%m-%d', 'now') "
        "AND exit_time IS NOT NULL";

    if (!query.exec(sql)) {
        qWarning() << "Earnings query error:" << query.lastError().text();
        return -1.0;
    }

    return query.next() ? query.value(0).toDouble() : 0.0;
}

QString EParkingSqlite::getStatusText()
{
    if (!checkDatabase()) return "统计信息暂时不可用";
    // 获取数据并验证有效性
    int count = getCurrentParkingCount();
    double earnings = getTodayEarnings();

    // 错误处理
    if (count < 0 || earnings < 0) {
        return "统计信息暂时不可用";
    }

    // 格式
    QLocale cn(QLocale::Chinese);
    return QString("当前共有%1辆车停放中，今日共计收费%2元")
        .arg(cn.toString(count))
        .arg(cn.toCurrencyString(earnings, "¥", 2));
}

bool EParkingSqlite::isVehicleInParking(const QString& plateNumber)
{
    if (!checkDatabase()) return false;
    if (plateNumber.isEmpty()) return false;

    QSqlQuery query;
    query.prepare(
        "SELECT 1 FROM vehicle_records "
        "WHERE plate_number COLLATE NOCASE = :plate "  // 不区分大小写
        "AND exit_time IS NULL "
        "LIMIT 1"  // 优化查询性能
        );
    query.bindValue(":plate", plateNumber.trimmed());

    const bool success = query.exec();
    if (!success) {
        qCritical() << "Vehicle check failed:" << query.lastError().text()
        << "for plate:" << plateNumber;
    }

    return success && query.next();
}

QList<QVariantMap> EParkingSqlite::getParkingRecords(int limit, const QString& plateKeyword)
{
    checkDatabase();

    QList<QVariantMap> records;
    QSqlQuery query;

    // 动态构建SQL语句
    QString sql = "SELECT * FROM vehicle_records ";
    if (!plateKeyword.isEmpty()) {
        sql += "WHERE plate_number LIKE :plate ";
    }
    sql += "ORDER BY entry_time DESC LIMIT :limit";

    query.prepare(sql);

    // 绑定车牌参数（带模糊匹配）
    if (!plateKeyword.isEmpty()) {
        query.bindValue(":plate", QString("%%1%").arg(plateKeyword.trimmed()));
    }
    query.bindValue(":limit", limit);

    if (query.exec()) {
        while (query.next()) {
            QVariantMap record;
            QSqlRecord sqlRecord = query.record();
            for(int i = 0; i < sqlRecord.count(); i++) {
                record[sqlRecord.fieldName(i)] = query.value(i);
            }
            records.append(record);
        }
    } else {
        qWarning() << "Query parking records failed:" << query.lastError().text();
    }

    return records;
}


QDateTime EParkingSqlite::getEntryTime(const QString& plateNumber)
{
    QSqlQuery query(db);
    query.prepare("SELECT entry_time FROM vehicle_records "
                  "WHERE plate_number = :plate AND exit_time IS NULL");
    query.bindValue(":plate", plateNumber);

    if (query.exec() && query.next()) {
        return query.value(0).toDateTime();
    }
    return QDateTime();
}



QList<QVariantMap> EParkingSqlite::getInternalCar()
{
    checkDatabase();

    QList<QVariantMap> lists;
    QSqlQuery query;
    QString sql = "SELECT * FROM internal_vehicles";

    query.prepare(sql);

    if (query.exec()) {
        while (query.next()) {
            QVariantMap list;
            QSqlRecord sqlRecord = query.record();
            for(int i = 0; i < sqlRecord.count(); i++) {
                list[sqlRecord.fieldName(i)] = query.value(i);
            }
            lists.append(list);
        }
    } else {
        qWarning() << "Query parking records failed:" << query.lastError().text();
    }

    return lists;
}
